A common pattern in messaging middleware is that of the intermediary. The intermediary is a service that is communicatively situated between two messaging communication mediums and transfers application-level messages between them. As the term is used herein, “messages” means application-level messages unless otherwise noted. The application-level message is a message that may be consumed by an application at the application-level in the protocol stack.
The communication mediums that will be described further herein are one-way transacted message infrastructures such as a typical queue that queues messages. Sometimes, the messaging intermediary is augmented with routing functionality to form a routing intermediary service. In this case an inbound message may be examined by the routing intermediary service, and a collection of outbound destinations for the message is identified based on routing logic. The routing intermediary service then sends a copy of the inbound message it has received to each outbound destination in the identified collection, thereby enabling multicast routing functionality.
Conventional routing intermediary services may route message transactionally using a two-phase commit transaction. For each message, the intermediary creates a transaction, and then receives the inbound message under the transaction. Then, routing logic is applied against the content of the message that results in the identification of a collection of message consumers to be sent a copy of the message. A copy of the message is then sent under the transaction to each of the message consumers in the collection. If all messages are successfully sent, the transaction is committed.
If, however, an error occurs during the transaction, the transaction rolls back. However, the rollback will restore the state of the inbound message source. Furthermore, the intermediary has no state that recognizes that an attempt to dispatch the message has already been attempted. Accordingly, the intermediary would perhaps repeat the whole process all over again in a never ending sequence, since the same failure that was encountered during the first attempt might persist across many attempts.